package com.youlai.system.plugin.easyexcel;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.youlai.system.model.entity.*;
import com.youlai.system.model.vo.ScoreRecordImportVO;
import com.youlai.system.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.ibatis.exceptions.TooManyResultsException;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 成绩记录导入监听器
 */
@Slf4j
public class ScoreRecordImportListener extends MyAnalysisEventListener<ScoreRecordImportVO> {

    //培训地点
    private final SysLocationService locationService;

    //故障名称
    private final SysCourseService courseService;

    //问题分类
    private final SysQuestionService questionService;

    //整改措施
    private final SysMeasureService measureService;

    //部门管理
    private final SysDeptService deptService;

    //用户管理
    private final SysUserService userService;

    //成绩管理
    private final SysScoreService scoreService;

    //角色管理
    private final SysRoleService roleService;

    //用户角色管理
    private final SysUserRoleService userRoleService;

    private final DegreeDataExecService degreeDataExecService;

    private final SysFrequencyService frequencyService;

    private final SysMoldService moldService;

    private final Long deptId;
    private final Map<String, ImmutablePair<Long, Long>> pairMap = new HashMap<>();

    public ScoreRecordImportListener(Long deptId) {
        this.deptId = deptId;
        this.locationService = SpringUtil.getBean(SysLocationService.class);
        this.courseService = SpringUtil.getBean(SysCourseService.class);
        this.questionService = SpringUtil.getBean(SysQuestionService.class);
        this.measureService = SpringUtil.getBean(SysMeasureService.class);
        this.deptService = SpringUtil.getBean(SysDeptService.class);
        this.userService = SpringUtil.getBean(SysUserService.class);
        this.scoreService = SpringUtil.getBean(SysScoreService.class);
        this.roleService = SpringUtil.getBean(SysRoleService.class);
        this.userRoleService = SpringUtil.getBean(SysUserRoleService.class);
        this.degreeDataExecService = SpringUtil.getBean(DegreeDataExecService.class);
        this.frequencyService = SpringUtil.getBean(SysFrequencyService.class);
        this.moldService = SpringUtil.getBean(SysMoldService.class);
    }

    @Override
    public String getMsg() {
        // 总结信息
        String summaryMsg = StrUtil.format("导入成绩记录结束：成功{}条，失败{}条；<br/>{}", validCount, invalidCount, msg);
        return summaryMsg;
    }

    @Override
    public void invoke(ScoreRecordImportVO scoreRecordImportVO, AnalysisContext analysisContext) {
        log.info("解析到一条成绩记录数据:{}", JSONUtil.toJsonStr(scoreRecordImportVO));
        // 校验数据
        StringBuilder validationMsg = new StringBuilder();

        if (scoreRecordImportVO.getDate() == null) {
            validationMsg.append("日期为空");
        }

        if (scoreRecordImportVO.getTime() == null) {
            scoreRecordImportVO.setTime("00:00");
        }

        if (StrUtil.isBlank(scoreRecordImportVO.getDriver())) {
            validationMsg.append("培训司机为空");
        }

        if (StrUtil.isBlank(scoreRecordImportVO.getCarName())) {
            validationMsg.append("车队为空");
        }

        if (StrUtil.isBlank(scoreRecordImportVO.getScore())) {
            validationMsg.append("分数为空");
        }

        if (StrUtil.isBlank(scoreRecordImportVO.getFailCount())) {
            validationMsg.append("问题项数为空");
        }

        SysScore score = new SysScore();
        score.setCheckDate(scoreRecordImportVO.getDate());//日期
        score.setCheckTime(scoreRecordImportVO.getTime());//时间
        score.setCarGroupNumber(scoreRecordImportVO.getCarNumber());//车组号
        score.setQuestionContent(scoreRecordImportVO.getDescription());//具体问题项点

        if (StrUtil.isNotBlank(scoreRecordImportVO.getScore()) && NumberUtil.isNumber(scoreRecordImportVO.getScore())) {
            score.setScore(Integer.valueOf(scoreRecordImportVO.getScore()));//分数
        }

        if (StrUtil.isNotBlank(scoreRecordImportVO.getFailCount()) && NumberUtil.isNumber(scoreRecordImportVO.getFailCount())) {
            score.setQuestionCount(Integer.valueOf(scoreRecordImportVO.getFailCount()));//问题项数
        }


        //异常问题解决
        if (StrUtil.isNotBlank(scoreRecordImportVO.getTime()) && scoreRecordImportVO.getTime().contains(".")) {
            scoreRecordImportVO.setTime(scoreRecordImportVO.getTime().replace(".", ":"));
        }

        if (StrUtil.isNotBlank(scoreRecordImportVO.getTime()) && scoreRecordImportVO.getTime().contains(";")) {
            scoreRecordImportVO.setTime(scoreRecordImportVO.getTime().replace(";", ":"));
        }

        if (StrUtil.isNotBlank(scoreRecordImportVO.getTime()) && !scoreRecordImportVO.getTime().contains(":")) {
            StringBuilder sb = new StringBuilder(scoreRecordImportVO.getTime());
            sb.insert(scoreRecordImportVO.getTime().length() / 2, ":");
            scoreRecordImportVO.setTime(sb.toString());
        }

        //部门处理
        if (StrUtil.isNotBlank(scoreRecordImportVO.getCarName()) && StrUtil.isNotBlank(scoreRecordImportVO.getDriver())) {
            SysDept dept = deptService.getDeptBy(this.deptId, scoreRecordImportVO.getCarName());
            if (dept == null) {
                SysDept parent = deptService.getById(this.deptId);
                validationMsg.append("没有在指定的父部门【" + parent + "】下找到名称为【" + scoreRecordImportVO.getCarName() + "】子部门(车队)");
            } else {
                try {
                    SysUser user = userService.getBy(this.deptId, scoreRecordImportVO.getDriver());
                    if (user != null) {
                        user.setDeptId(dept.getId());
                        userService.updateById(user);
                    } else {
                        user = userService.getBy(dept.getId(), scoreRecordImportVO.getDriver());
                    }

                    if (user == null) {
                        validationMsg.append("数据库中用户表内没有找到该用户！");
                    } else {
                        score.setStudentId(user.getId());
                    }
                } catch (TooManyResultsException exception) {
                    validationMsg.append("在同一个部门找到同名的用户，这个属于脏数据了，请想办法解决，该用户名称为：" + scoreRecordImportVO.getDriver());
                }

            }
        } else {
            validationMsg.append("车队或者培训司机不存在");
        }

        if (StrUtil.isBlank(scoreRecordImportVO.getCourse())) {
            validationMsg.append("故障名称为空");
        } else {
            //故障名称处理
            SysCourse course = courseService.getByContentEqual(scoreRecordImportVO.getCourse());
            if (course == null) {
                course = courseService.saveByContent(scoreRecordImportVO.getCourse());
            }
            score.setCourseId(course.getId());
            if (score.getStudentId() != null) {
                SysUser user = userService.getById(score.getStudentId());
                if (user == null || user.getGradeId() == null) {
                    validationMsg.append("司机职级不存在！");
                } else {
                    score.setGradeId(user.getGradeId());
                    SysFrequency frequency = frequencyService.getOneByGradeIdAndCourseId(user.getGradeId(), score.getCourseId());
                    if (frequency == null || frequency.getMoldId() == null) {
                        validationMsg.append("职级故障科目评估频次不存在！");
                    } else {
                        SysMold mold = moldService.getById(frequency.getMoldId());
                        if (mold == null || mold.getFrequency() == null) {
                            validationMsg.append("职级故障科目故障类型故障评估频次不存在");
                        } else {
                            score.setFrequency(mold.getFrequency());
                        }
                    }
                }
            }
        }

        //问题分类处理
        if (StrUtil.isNotBlank(scoreRecordImportVO.getQuestion())) {
            SysQuestion question = questionService.getByContentEqual(scoreRecordImportVO.getQuestion());
            if (question == null) {
                question = questionService.saveByContent(scoreRecordImportVO.getQuestion());
            }
            score.setQuestionId(question.getId());
            question = questionService.getById(score.getQuestionId());

            if (question == null || question.getQuota() == null) {
                validationMsg.append("问题分类指标性质不存在!");
            } else {
                score.setQuota(question.getQuota());
            }

        } else {
            validationMsg.append("问题分类不存在");
        }


        if (validationMsg.isEmpty()) {
            DateTime dateTime = DateUtil.parse(scoreRecordImportVO.getDate() + " " + scoreRecordImportVO.getTime());
            score.setPlanTime(dateTime.toLocalDateTime());
            score.setRealTime(dateTime.toLocalDateTime());

            //培训地点处理
            if (StrUtil.isNotBlank(scoreRecordImportVO.getLocation())) {
                SysLocation location = locationService.getByContentEqual(scoreRecordImportVO.getLocation());
                if (location == null) {
                    location = locationService.saveByContent(scoreRecordImportVO.getLocation());
                }
                score.setLocationId(location.getId());
            }

            //整改措施处理
            if (StrUtil.isNotBlank(scoreRecordImportVO.getMeasure())) {
                SysMeasure measure = measureService.getByContentEqual(scoreRecordImportVO.getMeasure());
                if (measure == null) {
                    measure = measureService.saveByContent(scoreRecordImportVO.getMeasure());
                }
                score.setMeasureId(measure.getId());
            }

            //内训师处理
            if (StrUtil.isNotBlank(scoreRecordImportVO.getTeacher())) {
                SysRole role = roleService.getTeacherRole();
                List<Long> userIdList = userRoleService.getUserIdBy(role.getId());
                if (CollectionUtil.isNotEmpty(userIdList)) {
                    SysUser teacher = userService.getBy(userIdList, scoreRecordImportVO.getTeacher());
                    if (teacher != null) {
                        score.setTeacherId(teacher.getId());
                    }
                }
            }

            //保存成绩
            SysScore dbScore = scoreService.getBy(score.getCheckDate(), score.getCheckTime(), score.getStudentId(), score.getCourseId());
            if (dbScore != null) {
                BeanUtil.copyProperties(score, dbScore, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
                scoreService.updateById(dbScore);
            } else {
                scoreService.save(score);
            }

            ImmutablePair<Long, Long> pair = ImmutablePair.of(score.getStudentId(), score.getCourseId());
            pairMap.put(score.getStudentId() + "," + score.getCourseId(), pair);
            validCount++;
        } else {
            invalidCount++;
            msg.append("第" + (validCount + invalidCount) + "行数据校验失败：").append(JSONUtil.toJsonStr(scoreRecordImportVO)).append(validationMsg + "<br/>");
        }

    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        pairMap.values().forEach(pair -> {
            degreeDataExecService.execResetExamPeriodDegreeScore(pair.getLeft(), pair.getRight());
            degreeDataExecService.execSingleStuCourseExam(pair.getLeft(), pair.getRight());
        });
    }
}
